package edu.indiana.d2i.vmm;

import java.io.FileReader;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Properties;

import javax.xml.bind.JAXBException;
import javax.xml.stream.XMLStreamException;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.llom.util.AXIOMUtil;

import edu.indiana.d2i.vmm.job.SigiriHTRCJobDescription;
import edu.indiana.d2i.vmm.job.SigiriHTRCConstants;
import edu.indiana.d2i.vmm.job.rsl.JobTypeEnumeration;
import edu.indiana.extreme.sigiri.SigiriServiceStub;
import edu.indiana.extreme.sigiri.SigiriServiceStub.HpcResourceName;
import edu.indiana.extreme.sigiri.SigiriServiceStub.JobId;
import edu.indiana.extreme.sigiri.SigiriServiceStub.JobStatus;
import edu.indiana.extreme.sigiri.SigiriServiceStub.JobSubmissionParameters;
import edu.indiana.extreme.sigiri.SigiriServiceStub.XMLContent;
import edu.indiana.extreme.sigiri.util.Constants;

public class SigiriHTRCClient implements Runnable {
	private String jobDescriptionXMLStr;
	private final SigiriServiceStub stub;

	private String endpoint;
	private String exeName;
	private String exePath;
	private String propName;
	private String propPath;
	private String executableargs;
	private String imagetype;
	private String outputfile;
	private int imagenum;
	
	private void loadProperties(String propfile) throws IOException {
		Properties prop = new Properties();
		prop.load(new FileReader(propfile));
		endpoint = prop.getProperty("wsendpoint");
		exeName = prop.getProperty("executable");
		exePath = prop.getProperty("executablepath");
		propName = prop.getProperty("property");
		propPath = prop.getProperty("propertypath");
		executableargs = prop.getProperty("executableargs");
		imagetype = prop.getProperty("imagetype");
		imagenum = Integer.valueOf(prop.getProperty("imagenum"));
		outputfile = prop.getProperty("outputfile");
	}
	
	public SigiriHTRCClient(String propfile) throws IOException {
		loadProperties(propfile);
		stub = new SigiriServiceStub(endpoint);
	}
	
	public void setJobDescription(SigiriHTRCJobDescription conf)
			throws JAXBException {
		this.jobDescriptionXMLStr = conf.toXMLString();
		System.out.println(jobDescriptionXMLStr);
	}

	@SuppressWarnings("deprecation")
	public JobStatus submitJob() throws RemoteException, XMLStreamException {
		JobSubmissionParameters parameters = new JobSubmissionParameters();
		parameters.setHpcResource(HpcResourceName.Quarry);
		OMElement omelement = AXIOMUtil.stringToOM(jobDescriptionXMLStr);
//		OMElement omelement = AXIOMUtil.stringToOM("<sample>this is a sample</sample>");
		XMLContent xmlContent = new XMLContent();
		xmlContent.setExtraElement(omelement);
		parameters.setJobDescriptionXML(xmlContent);
		parameters.setCallbackURL("www.google.com");

		return stub.submitJob(parameters);
	}

	@Override
	public void run() {
		try {
			SigiriHTRCJobDescription.Builder builder = new SigiriHTRCJobDescription.Builder();
			builder.setExecutable(exeName, exePath);
			builder.setPropertyFile(propName, propPath);
			builder.setUserID("User_Id_1");
			builder.setImageInfo(imagetype, imagenum);
			builder.setSoftwareFramework(SigiriHTRCConstants.EXECUTABLE_TYPE_JAR);
			builder.setOutputFile(outputfile);
			builder.setJobType(JobTypeEnumeration.SINGLE);
			String[] args = executableargs.split("\\s+");
			for (int i = 0; i < args.length; i++) 
				builder.addUserArgsInOrder(args[i]);
			SigiriHTRCJobDescription conf = builder.build();
			this.setJobDescription(conf);
			
			JobStatus jobStatus = submitJob();
			JobId jobId = new JobId();
	        jobId.setJobId(jobStatus.getJobId());
			System.out.println("Job ID returned from server: " + jobStatus.getJobId());
			String statusStr = jobStatus.getStatus();
			while (!statusStr.equals(Constants.JobStatus.JOB_COMPLETED)) {
				System.out.println("Job status: " + statusStr);
				if (statusStr.contains("FAILED")) break;
				
				Thread.sleep(2000);
				statusStr = stub.checkStatus(jobId).getStatus();
			}
			System.out.println("Client quits for " + statusStr);
		} catch (JAXBException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (XMLStreamException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/* test client */
	public static void main(String[] args) throws IOException {
		if (args.length != 1) {
			System.out.println("Usage: SigiriHTRCClient propertyfile");
			System.exit(-1);
		}
		
		SigiriHTRCClient client = new SigiriHTRCClient(args[0]);
		new Thread(client).start();
	}
}
